package com.yh.service.impl;

import com.yh.config.OtherSource;
import com.yh.dao.CommentDao;
import com.yh.dao.MovieDao;
import com.yh.dao.UserDao;
import com.yh.entity.Comment;
import com.yh.entity.Movie;
import com.yh.entity.User;
import com.yh.service.CommentService;
import com.yh.utils.Constants;
import com.yh.vo.CustomPageAndNavigate;
import com.yh.utils.ImgUrl;
import com.yh.vo.CommentVO;
import io.minio.MinioClient;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author yuhuan
 * @date 2022/01/13
 */
@DubboService
public class CommentServiceImpl implements CommentService {
    /**
     * 日志
     */
    private static final Logger logger = Logger.getLogger(CommentServiceImpl.class);

    @Autowired
    private CommentDao commentDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private MovieDao movieDao;
    @Autowired
    private OtherSource otherSource;
    @Autowired
    private MinioClient minioClient;

    @Override
    public CustomPageAndNavigate findCommentAll(Integer pageNum, Integer pageSize) {
        List<Comment> commentList = commentDao.findCommentAll();
        List<CommentVO> comments = new ArrayList<>();
        commentList.forEach(comment -> {
            CommentVO commentToVo = findCommentToVo(comment, true);
            comments.add(commentToVo);
        });
        return new CustomPageAndNavigate(pageNum, pageSize, comments);
    }

    @Override
    public CommentVO findCommentByUserAndMovie(CommentVO commentVO) {
        Comment comment = commentDao.findCommentByUserAndMovie(commentVO.getUserId(), commentVO.getMovieId());
        if (ObjectUtils.isEmpty(comment)) {
            return null;
        }
        commentVO.setComment(comment);
        return commentVO;
    }

    @Override
    public CustomPageAndNavigate initCommentVoListToPage(Integer movieId, Integer pageNum, Integer pageSize) {
        if (ObjectUtils.isEmpty(movieId)) {
            logger.debug(">>>>> 要求按影片ID寻找影评，但是你没有传递正确的影片ID");
            return null;
        }
        if (ObjectUtils.isEmpty(pageNum)) {
            pageNum = Constants.PageParam.PAGE_NUM;
        }
        if (ObjectUtils.isEmpty(pageSize)) {
            pageSize = Constants.PageParam.PAGE_SIZE;
        }
        List<CommentVO> commentVos = initCommentVoList(movieId);
        if (ObjectUtils.isEmpty(commentVos)) {
            return null;
        }
        return new CustomPageAndNavigate(pageNum, pageSize, commentVos);
    }

    @Override
    public boolean addOrUpdateComment(CommentVO commentVO) {
        Comment comment = new Comment();
        // 字段信息拷贝（只对同字段进行拷贝，并且会丢失目标对象原有的属性值）
        BeanUtils.copyProperties(commentVO, comment);
        // 查看该用户是否已经对当前影片给出了评分
        Comment commentByUser = commentDao.findCommentByUserAndMovie(comment.getUserId(), comment.getMovieId());
        // 如果该用户是初次评分，就将当前评分记录添加到数据库
        if (ObjectUtils.isEmpty(commentByUser)) {
            // 添加评论时间
            comment.setCommentTime(new Date());
            return commentDao.insertComment(comment) > 0 ? true : false;
        }
        // 在原评论的基础上修改评分和评论
        comment.setCommentId(commentByUser.getCommentId());
        return commentDao.updateComment(comment) > 0 ? true : false;
    }

    @Override
    public boolean addCommentIfNotExist(CommentVO commentVO) {
        // 查看该用户是否已经对当前影片给出了评分
        Comment commentByUser = commentDao.findCommentByUserAndMovie(commentVO.getUserId(), commentVO.getMovieId());
        if (ObjectUtils.isEmpty(commentByUser)) {
            return addOrUpdateComment(commentVO);
        }
        return false;
    }

    /**
     * 根据电影信息初始化所有的影评模型
     */
    private List<CommentVO> initCommentVoList(int movieId) {
        List<CommentVO> commentVos = new ArrayList<>();
        // 找到影评实体信息
        List<Comment> comments = commentDao.findCommentByMovieId(movieId);
        if (ObjectUtils.isEmpty(comments)) {
            logger.debug(movieId + "号影片的影评信息没有找到");
            return commentVos;
        }
        // 封装影评数据模型
        comments.forEach(comment -> {
            CommentVO commentToVo = findCommentToVo(comment, false);
            commentVos.add(commentToVo);
        });
        return commentVos;
    }

    /**
     * 查询单个影评的详细信息（返回影评响应模型）
     *
     * @aotuMovieName 是否需要封装影片的名称
     */
    private CommentVO findCommentToVo(Comment comment, boolean aotuMovieName) {
        User user = userDao.findUserById(comment.getUserId());
        // 处理头像地址
        user = ImgUrl.userImageHandler(minioClient, otherSource, user);
        // 实体数据封装
        CommentVO commentVO = createCommentVO(comment, user);
        if (aotuMovieName) {
            // 封装影片的名称
            Movie movie = movieDao.findMovieByIdNeedIgnoreState(comment.getMovieId());
            commentVO.setMovieCnName(movie.getMovieCnName());
        }
        return commentVO;
    }

    /**
     * 创建影评响应模型（将电影的评论和关联的用户信息都封装到模型中）
     */
    private CommentVO createCommentVO(Comment comment, User user) {
        CommentVO vo = new CommentVO();
        // 属性拷贝
        BeanUtils.copyProperties(comment, vo);
        // 封装实体
        vo.setComment(comment);
        vo.setUser(user);
        return vo;
    }
}
